import React, { Component } from 'react';
import { Button, Icon, message, Modal, Upload, Row, Col } from 'antd';
import { ProFormCheckbox } from '@ant-design/pro-form';
import oss from 'ali-oss';
import moment from 'moment';
import { connect } from 'umi';
import './index.less';
import sldCover from "@/assets/sldCover.png";
import audioPng from "@/assets/audio.png";
import coverPng from "@/assets/cover.png";
import { LoadingOutlined, PlusOutlined, ToTopOutlined, DeleteOutlined, PlayCircleFilled } from '@ant-design/icons';
type UploadListType = 'text' | 'picture' | 'picture-card';

// 全局变量
const ossUrl = process.env.OSS_URL;

interface IProps {
  dispatch?: any;
  disabled?: boolean;
  onRef?: (ref: any) => void;
  onChange?: (fileList: any[]) => void;
  value?: any;
  businessName: string; // 上传时的业务名称
  maxNumber?: number; // 上传的最大个数
  fileType: string; // 上传的文件类型，以逗号分隔
  name?: string;
  showPreviewIcon?: boolean; // 是否展示预览按钮
  showRemoveIcon?: boolean; // 是否展示移除按钮
  size?: number; // 上传大小，单位M
  videoSize?: number;
  listType: UploadListType; // 支持三种基本样式 text, picture 和 picture-card
  hideAddButton?: boolean;
  canPreviewText?: boolean; // 是否可以预览文件类型的附件，目前采用浏览器直接打开的方式预览文件
  needBottomCard?: boolean;//是否需要底部卡片功能以及侧边置顶功能
  needLeftTip?: boolean;//是否需要右侧置顶提示功能
  isAvatar?: boolean//上传单个头像
  imgMaxNumber?: number;//图片上传的最大个数
  videoMaxNumber?: number;//视频上传的最大个数
  audioMaxNumber?: number;//音频上传的最大个数
  tipsArray?: any[];//上传tips
  showTip?: boolean;
  isSetHomeSlide?: any[],
  formRef?: any,
}

interface IState {
  loading: boolean;
  token: any;
  tenant_id: string | null;
  head: string | null;
  previewVisible: boolean;
  previewImage: string;
  isSetHomeSlide: any;
  avatarValue?: string;//头像初始值
  headerIndex: any;
  coverIndex: number;
}

@connect(({ aliyunOss }) => ({
  aliyunOss
}))
class AliyunOssUpload extends React.Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);
    this.state = {
      loading: false,
      // oss参数
      token: {},
      tenant_id: null,
      head: null,
      // 预览
      previewVisible: false,
      previewImage: '',
      isSetHomeSlide: [],
      headerIndex: null,
      coverIndex: -1
    };

  }



  async componentDidMount() {
    await this.init();
    // 如果是头像功能单独处理一下url
    let { isAvatar } = this.props;
    if (isAvatar) {
      this.setState({
        avatarValue: value && value.length > 0 && value[0].path || ''
      })
    }
    if (this.props.onRef) {
      this.props.onRef(this);
    }
  }


  // 初始化，获取oss参数
  init = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'aliyunOss/getTemOssAuth',
      payload: {},
      callback: (e: { code: number, data: any }) => {
        if (e.code === 1) {
          this.setState({
            token: {
              access_key_id: e.data.accessKeyId, // oss的key_id
              access_key_secret: e.data.accessKeySecret, // oss的secret
              OSS_ENDPOINT: e.data.endPoint, // 自己oss服务器的配置信息
              OSS_BUCKET: e.data.bucket, // 自己oss服务器的配置信息
              region: e.data.region,
              sts_token: e.data.securityToken,
            },
            tenant_id: e.data.tenantId,
            head: e.data.head,
          });
        }
      },
    });

  };

  // 生成oss对象
  client = () => {
    const { token } = this.state;
    return new oss({
      accessKeyId: token.access_key_id,
      accessKeySecret: token.access_key_secret,
      region: token.region,
      bucket: token.OSS_BUCKET,
      endpoint: token.OSS_ENDPOINT,
      stsToken: token.sts_token
    });
  };

  uploadPath = (path, file) => {
    const now = Date.now();
    const fileTypeArr = file.name ? file.name.split('.') : [];
    const fileType = fileTypeArr.length > 0 ? fileTypeArr[fileTypeArr.length - 1] : '';
    const url = fileType
      ? `${path}/${moment().format('YYYYMMDD')}/${now}.${fileType}`
      : `${path}/${moment().format('YYYYMMDD')}/${now}.${file.type.split('/')[1]}`;
    return url;
  };

  UploadToOss = (path, file) => {
    const url = this.uploadPath(path, file);
    return new Promise((resolve, reject) => {
      this.client()
        .multipartUpload(url, file)
        .then((data) => {
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  };

  // 上传本地文件到oss,存入sys_file表
  saveOssFile2sysfile = (params, cb) => {
    const { dispatch, businessName } = this.props;
    dispatch({
      type: 'aliyunOss/saveOssFile2sysfile',
      payload: {
        name: params.name,
        type: businessName,
        size: params.size,
        path: params.path,
        sort: params.sort,
      },
      callback: (e) => {
        if (e.code === 1) {
          cb(e.data);
        }
      },
    });
  };

  beforeUpload = (file, fileListNew) => {
    const { onChange, businessName, value, fileType, size, maxNumber, needBottomCard, isAvatar, imgMaxNumber, audioMaxNumber, videoMaxNumber, videoSize } = this.props;
    let typeArr = [];
    let isPass = false;
    let chooseFileType = file.name.split('.')[1]
    if (fileType) {
      typeArr = fileType.split(',');
      if ((typeArr || []).length > 0) {
        const fileTypeArr = file.name.split('.');
        const currentFileType = fileTypeArr[fileTypeArr.length - 1].toLowerCase();
        typeArr.map((item) => {
          if (item.indexOf(currentFileType) > -1) {
            isPass = true;
          }
        });
      }
    }

    if (!isPass && typeArr?.length) {
      message.error(`支持扩展名：${fileType}`);
      onChange([...value]);
      return false;
    }

    //对能同时上传图片，音视频做size的单独判断
    if ((chooseFileType === 'mp4' || chooseFileType === 'mov' || chooseFileType === 'MP4' || chooseFileType === 'MOV' || chooseFileType === 'mp3' || chooseFileType === 'wma') && videoSize) {
      const isLt128M = file.size / 1024 / 1024 < videoSize;
      if (!isLt128M) {
        message.error(`附件大小不能超过${videoSize}MB!`);
        onChange([...value]);
        return false;
      }
    } else {
      if (size) {
        const isLt128M = file.size / 1024 / 1024 < size;
        if (!isLt128M) {
          message.error(`附件大小不能超过${size}MB!`);
          onChange([...value]);
          return false;
        }
      }
    }


    this.setState({
      loading: true,
    });
    const reader = new FileReader();
    const path = `/saas2/publicFile/${businessName}`;
    reader.readAsDataURL(file);
    reader.onloadend = () => {
      this.UploadToOss(path, file)
        .then((data) => {
          fileListNew[0].path = data.name;
          fileListNew[0].url = data.res.requestUrls
            .toString()
            .split('?')[0]
            .replace(this.state.head, '');
          if (fileListNew[0].url) {
            fileListNew[0].url = fileListNew[0].url.replace('http://', 'https://');
          }

          this.saveOssFile2sysfile(fileListNew[0], (res) => {
            if (isAvatar) {
              this.setState({
                avatarValue: res.path,
                loading: false
              })
              onChange && onChange(res)
            } else {
              let arr = (value || []).concat();
              const _obj: any = {
                id: res.id,
                uid: res.id,
                name: res.name,
                path: res.path,
                size: res.size,
                url: ossUrl + res.path,
                type: res.type,
                businessName: businessName
              }
              if (fileType === '.mp4') {
                let url = URL.createObjectURL(file);
                let audioElement = new Audio(url);
                audioElement.addEventListener("loadedmetadata", (_event) => {
                  _obj.duration = audioElement.duration;
                });
              }
              arr.push(_obj);

              // 一般上传组件，不需要底部cardList
              if (!needBottomCard) {
                if (maxNumber) {
                  arr = arr.slice(-maxNumber);
                }
              } else {
                // 需要底部cardList操作 参照（村务动态新建弹窗）
                let imgArr = arr.filter(item => {
                  let fileType = item.path.split('.')[1];
                  return fileType == 'png' || fileType == 'jpg' || fileType == 'jpeg' || fileType == 'PNG' || fileType == 'JPG' || fileType == 'JPEG'
                });
                let videoArr = arr.filter(item => {
                  let fileType = item.path.split('.')[1];
                  return fileType == 'mp4' || fileType == 'mov' || fileType == 'MP4' || fileType == 'MOV'
                })
                let audioArr = arr.filter(item => {
                  let fileType = item.path.split('.')[1];
                  return fileType == 'mp3' || fileType == 'wma' || fileType == 'wav' || fileType == 'MP3' || fileType == 'WMA' || fileType == 'WAV'
                })
                if (imgArr.length > (imgMaxNumber || 6)) {
                  message.warning(`最多可上传${imgMaxNumber || 6}张图片`);
                  arr.splice(arr.length - 1, 1);
                }
                if (videoArr.length > (videoMaxNumber || 1)) {
                  message.warning(`最多可上传${videoMaxNumber || 1}个视频`);
                  arr.splice(arr.length - 1, 1);
                }
                if (audioArr.length > (audioMaxNumber || 1)) {
                  message.warning(`最多可上传${audioMaxNumber || 1}个音频`);
                  arr.splice(arr.length - 1, 1);
                }
              }
              onChange && onChange([...arr]);
              this.setState({
                loading: false
              });
            }
          });
        })
        .catch((e) => {
          this.setState({
            loading: false,
          });
          message.error('上传失败');
        });
    };
    return false;


  };

  onRemoveUpload = (file) => {
    const { value, onChange, formRef } = this.props;
    const arr = (value || []).concat();
    const index = arr.findIndex((item) => item.uid ? item.uid == file.uid : item.id == file.id);
    if (index > -1) {
      arr.splice(index, 1);
    }
    onChange && onChange(arr);
  };

  onRemove = (file) => {
    const { value, onChange, formRef } = this.props;
    const arr = (value || []).concat();
    const index = arr.findIndex((item) => item.uid ? item.uid == file.uid : item.id == file.id);
    if (file.isSetToIndex === 1) {
      this.setState({
        isSetHomeSlide: ['是否设置为首页轮播图']
      })
      formRef?.current?.setFieldsValue({ 'isSetHomeSlide': ['是否设置为首页轮播图'] })
    }

    if (arr.length === 1) {
      this.setState({
        isSetHomeSlide: []
      })
      formRef?.current?.setFieldsValue({ 'isSetHomeSlide': [] })
    }

    if (index > -1) {
      arr.splice(index, 1);
    }

    // 删除完后，校验剩下的是否有图片，么有的话重置首页轮播为空
    let imgArr = arr.filter((item: any) => item.path.split('.')[1] === 'jpg' || item.path.split('.')[1] === 'jpeg' || item.path.split('.')[1] === 'png' || item.path.split('.')[1] === 'JPG' || item.path.split('.')[1] === 'JPEG' || item.path.split('.')[1] === 'PNG')
    if (!imgArr || imgArr.length === 0) {
      this.setState({
        isSetHomeSlide: []
      })
      formRef?.current?.setFieldsValue({ 'isSetHomeSlide': [] })
    }

    onChange && onChange(arr);

  };

  handlePreview = (file) => {
    const { listType, canPreviewText } = this.props;
    if (listType === 'text') {
      // 预览文档
      if (canPreviewText) {
        const path = `${process.env.OSS_URL}${file.path}`;
        window.open(path, '_blank');
      }
    } else {
      if (!file.name) {
        this.setState({
          previewImage: file.url,
          previewVisible: true,
        });
      } else {
        if (file.name.indexOf('png') > -1 || file.name.indexOf('jpg') > -1 || file.name.indexOf('jpeg') > -1 || file.name.indexOf('PNG') > -1 || file.name.indexOf('JPG') > -1 || file.name.indexOf('JPEG') > -1) {
          this.setState({
            previewImage: file.url || file.thumbUrl,
            previewVisible: true,
          });


        } else {
          const path = `${process.env.OSS_URL}${file.path}`;
          window.open(path, '_blank');
        }
      }

    }
  };

  handleCancel = () => this.setState({ previewVisible: false });

  //底部需要有卡片图，鼠标移入移出事件
  mouseFnEnter = (index) => {
    if (this.props.disabled) return;
    let _index = index
    if (index === this.props.value.length) {
      _index = 0
    }
    this.props.value[_index].isHover = true
    let itemArray = document.getElementsByClassName('attach-item');
    itemArray[_index].classList.add('show-tip');
  }
  //底部需要有卡片图，鼠标移入移出事件
  mouseFnLeave = (index) => {
    if (this.props.disabled) return;
    let _index = index
    if (index === this.props.value.length) {
      _index = 0
    }
    this.props.value[_index].isHover = true
    let itemArray = document.getElementsByClassName('attach-item');
    itemArray[_index].classList.remove('show-tip');
  }

  // 设置图片为首页轮播
  onsetToIndex = (item) => {
    let itemArray = document.getElementsByClassName('attach-item');
    let { onChange, value } = this.props;
    let arr = value?.concat([]);
    arr?.forEach((child, idx) => {
      if (child.id == item.id) {
        child.isSetToIndex = 1
        itemArray[idx].classList.add('set-index');
      } else {
        child.isSetToIndex = 0;
        itemArray[idx].classList.remove('set-index');
      }
    })
    onChange && onChange(arr);
  }

  // 设置图片为视频封面
  onsetToPoster = (item) => {
    let itemArray = document.getElementsByClassName('attach-item');
    let { onChange, value } = this.props;
    let arr = value?.concat([]);
    arr?.forEach((child, idx) => {
      if (child.id == item.id) {
        child.isPoster = 1
        itemArray[idx].classList.add('set-poster');
      } else {
        child.isPoster = 0;
        itemArray[idx].classList.remove('set-poster');
      }
    })
    onChange && onChange(arr);
  }

  onSetHomeSlide = (value: any) => {
    let _headerIndex = value?.findIndex(item => item.isSetToIndex == 1)
    this.setState({
      isSetHomeSlide: _headerIndex > -1 ? ['是否设置为首页轮播图'] : []
    })
  }

  render() {
    const { previewVisible, previewImage, loading, avatarValue, headerIndex, coverIndex, isSetHomeSlide } = this.state;
    const {
      name,
      listType,
      disabled,
      maxNumber,
      fileType,
      needBottomCard,
      needLeftTip,
      hideAddButton,
      size,
      isAvatar,
      tipsArray,
      showPreviewIcon,
      showRemoveIcon,
      showTip = true,
    } = this.props;
    const { value } = this.props;
    const uploadIconButton = (
      <div>
        {loading ? <LoadingOutlined /> : <PlusOutlined />}
        <div className="ant-upload-text" dangerouslySetInnerHTML={{ __html: name || '上传' }}></div>
      </div>
    );
    const uploadTextButton = (
      <Button loading={loading}>
        <ToTopOutlined />{name || '点击上传'}
      </Button>
    )

    return (
      <div className="clearfix AliyunOssUploadWrap">
        <Row>
          <Col span={needBottomCard ? 5 : 24}>
            <Upload
              disabled={disabled || loading}
              listType={isAvatar ? 'picture-card' : listType}
              fileList={needBottomCard ? [] : value}
              onRemove={this.onRemoveUpload}
              onPreview={this.handlePreview}
              beforeUpload={this.beforeUpload}
              showUploadList={{
                showPreviewIcon: showPreviewIcon || true,
                showRemoveIcon: showRemoveIcon || true,
              }}
            >
              {needBottomCard ? uploadIconButton :
                isAvatar ? (avatarValue ? <img style={{ width: 120, height: 120 }} src={avatarValue && avatarValue.indexOf('http') > -1 ? avatarValue : `${ossUrl}${avatarValue}`} /> : uploadIconButton) :
                  listType === "text" ? (
                    !hideAddButton && (maxNumber ? (value || []).length < maxNumber : true) && uploadTextButton
                  ) : (
                    (value || []).length < maxNumber && uploadIconButton
                    //  
                  )
              }
            </Upload>
          </Col>
          {
            needLeftTip &&
            <Col span="19" className="rightCom">
              <ProFormCheckbox.Group
                layout="horizontal"
                name="isSetHomeSlide"
                label=""
                disabled={!value || value?.length === 0 || value?.findIndex((item: any) => item.path.split('.')[1] === 'jpg' || item.path.split('.')[1] === 'jpeg' || item.path.split('.')[1] === 'png' || item.path.split('.')[1] === 'JPG' || item.path.split('.')[1] === 'JPEG' || item.path.split('.')[1] === 'PNG') === -1}
                options={['是否设置为首页轮播图']}
                fieldProps={{
                  value: isSetHomeSlide,
                  onChange: (e) => {
                    this.setState({
                      isSetHomeSlide: e
                    })
                    if (e.length == 0) {
                      let itemArray = document.getElementsByClassName('attach-item');
                      value?.forEach((item, index) => {
                        item.isSetToIndex = 0;
                        itemArray[index].classList.remove('set-index');
                      })
                    } else {
                      let hasSetIndex = value?.findIndex((item: any) => item.isSetToIndex === 1);
                      let firstImg = value?.find((item: any) => item.path.split('.')[1] === 'jpg' || item.path.split('.')[1] === 'jpeg' || item.path.split('.')[1] === 'png' || item.path.split('.')[1] === 'JPG' || item.path.split('.')[1] === 'JPEG' || item.path.split('.')[1] === 'PNG')
                      let itemArray = document.getElementsByClassName('attach-item');
                      if ((!hasSetIndex || hasSetIndex === -1) && firstImg) {
                        value?.forEach((item, index) => {
                          if (item.id === firstImg.id) {
                            item.isSetToIndex = 1;
                            itemArray[index].classList.add('set-index');
                          }
                        })
                      }
                    }
                  }
                }
                }
              />
              <div className="mind">设置首页显示必须设置一张图片为首页展示图。</div>
              {/* <div className="mind">为了内容更快的加载，必须设置一张图片为视频的封面图。</div> */}
            </Col>
          }

        </Row>

        {showTip && <div style={{ color: 'rgba(0,0,0,0.45)', fontSize: '14px' }}>支持扩展名：{fileType} {!tipsArray && size && <span style={{ marginLeft: '5px' }}>，不超过{size}M</span>}</div>}
        {tipsArray && tipsArray.map((tip) => {
          return (
            <div className="mind">{tip}</div>
          )
        })}
        {needBottomCard && value && value.length > 0 && <div className="attach-wrap">
          {value.map((item, index) => {
            return (
              <>
                {
                  item.path.indexOf('.mp4') > -1 || item.path.indexOf('.mov') > -1 ?
                    <div className='attach-item' onMouseEnter={() => { this.mouseFnEnter(index) }} onMouseLeave={() => { this.mouseFnLeave(index) }} key={`video_${index}`} onClick={() => {
                      window.open(ossUrl + item.path, '_blank')
                    }}>
                      <video src={ossUrl + item.path} ></video>
                      <PlayCircleFilled />
                      <div className="hover-del" onClick={(e) => { e.stopPropagation(); this.onRemove(item) }}><DeleteOutlined /></div>
                    </div> :
                    item.path.indexOf('.mp3') > -1 || item.path.indexOf('.wma') > -1 || item.path.indexOf('.wav') > -1 ?
                      <div className='attach-item' onMouseEnter={() => { this.mouseFnEnter(index) }} onMouseLeave={() => { this.mouseFnLeave(index) }} key={`audio_${index}`} onClick={() => {
                        window.open(ossUrl + item.path, '_blank')
                      }}>
                        <img src={audioPng} style={{ height: '120px' }} />
                        <div className="hover-del" onClick={(e) => { e.stopPropagation(); this.onRemove(item) }}><DeleteOutlined /></div>
                      </div> :
                      <div onClick={() => {
                        this.setState({
                          previewImage: ossUrl + item.path,
                          previewVisible: true,
                        });
                      }} key={`attach_${index}`} className={`${item.isSetToIndex == 1 ? 'set-index' : ''} attach-item`} onMouseEnter={() => { this.mouseFnEnter(index) }} onMouseLeave={() => { this.mouseFnLeave(index) }}>
                        <img src={ossUrl + item.path} />
                        <div onClick={(e) => { e.stopPropagation(); this.onsetToIndex(item) }} className={isSetHomeSlide.length > 0 ? 'hover-wrap show-hover' : 'hover-wrap'} >
                          {/* {value.filter(item => (item.path.indexOf('.mp4') > -1 || item.path.indexOf('.mov') > -1)).length > 0 && <span onClick={(e) => { e.stopPropagation(); this.onsetToPoster(item) }}>设为视频封面</span>} */}
                          {isSetHomeSlide.length > 0 && <span>设为首页滚动图</span>}
                        </div>
                        <img className="sld-cover" src={sldCover} />
                        <img className="pst-cover" src={coverPng} />
                        <div className="hover-del" onClick={(e) => { e.stopPropagation(); this.onRemove(item) }}><DeleteOutlined /></div>
                      </div>

                }
              </>
            )
          })}

        </div>}

        <Modal
          width={800}
          closable
          maskClosable={false}
          visible={previewVisible}
          footer={null}
          onCancel={this.handleCancel}
        >
          <div style={{ padding: '24px 0' }}>
            <img alt="example" style={{ width: '100%' }} src={previewImage} />
          </div>

        </Modal>
      </div>
    );
  }
}

export default AliyunOssUpload;
